package com.lclz.util;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.codehaus.jackson.map.ObjectMapper;

import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.uri.UriComponent;

/**
 * 使用jersey，需要把restful规划成如下形式 <br/>
 * 系统部署地址 | 类Path | 方法Path<br/>
 * 或者 <br/>
 * API服务器地址 | API接口 | API接口地址<br/>
 * 举例<br/>
 * server | restURI | path<br/>
 * http://127.0.0.1/system_context |/getinfo | /name/a.json<br/>
 * 
 * @author weiw
 * 
 */
public class JerseyClientUtil {

	/**
	 * 创建JerseyClient实例
	 * 
	 * @param server
	 *            API服务器地址
	 * @param restURI
	 *            API接口
	 * @return webResource
	 */
	private static WebResource getWebResource(String server, String restURI) {
		String resourceUrl = server + restURI;
		WebResource webResource = JerseyClientLazyLoadedSingleton.getInstance().resource(resourceUrl);
		return webResource;
	}

	public String urlEncode(String url) {
		return UriComponent.encode(url, UriComponent.Type.PATH_SEGMENT);
	}

	/**
	 * Post请求的处理
	 * 
	 * @param server
	 *            API服务器地址
	 * @param restURI
	 *            API接口
	 * @param path
	 *            API接口地址
	 * @param object
	 *            需要post提交的对象（传入实体本类型）
	 * @return 服务器返回内容
	 * @throws RESTFulException
	 *             截获此方法的所有异常，并统一throw MyException
	 * 
	 */
	public static String post(String server, String restURI, String path, Object object) throws RESTFulException {
		String result = "";
		ClientResponse response = null;
		try {
			response = getWebResource(server, restURI).path(path).header("Content-Type", MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(ClientResponse.class, object);
			result = response.getEntity(String.class);
			//			System.out.println("result=" + result);
			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " post method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			throw new RESTFulException(-1, "NetWorkError", "post method throw ClientHandlerException [server=" + server + ";restURI=" + restURI + ";path=" + path + "]");
		}
		return result;
	}

	public static String post(String url, Object object) throws RESTFulException {
		String result = "";
		ClientResponse response = null;
		try {
			response = JerseyClientLazyLoadedSingleton.getInstance().resource(url).header("Content-Type", MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON)
					.post(ClientResponse.class, object);
			result = response.getEntity(String.class);
			//			System.out.println("result=" + result);
			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " post method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			throw new RESTFulException(-1, "NetWorkError", "post method throw ClientHandlerException");
		}
		return result;
	}

	/**
	 * Put请求的处理
	 * 
	 * @param server
	 *            API服务器地址
	 * @param restURI
	 *            API接口
	 * @param path
	 *            API接口地址
	 * @param object
	 *            需要put提交的对象（传入实体本类型）
	 * @return 服务器返回内容
	 * @throws RESTFulException
	 *             截获此方法的所有异常，并统一throw MyException
	 * 
	 */
	public static String put(String server, String restURI, String path, Object object) throws RESTFulException {

		String result = "";
		ClientResponse response = null;
		try {
			response = getWebResource(server, restURI).path(path).header("Content-Type", MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).put(ClientResponse.class, object);
			result = response.getEntity(String.class);

			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " put method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			throw new RESTFulException(-1, "NetWorkError", "put method throw ClientHandlerException");
		}

		return result;
	}

	/**
	 * DELETE请求的处理
	 * 
	 * @param server
	 *            API服务器地址
	 * @param restURI
	 *            API接口
	 * @param path
	 *            API接口地址
	 * @return 服务器返回内容
	 * @throws RESTFulException
	 *             截获此方法的所有异常，并统一throw MyException
	 */
	public static String delete(String server, String restURI, String path) throws RESTFulException {
		String result = "";
		ClientResponse response = null;
		try {
			response = getWebResource(server, restURI).path(path).header("Content-Type", MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).delete(ClientResponse.class);
			result = response.getEntity(String.class);

			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " delete method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			throw new RESTFulException(-1, "NetWorkError", "delete method throw ClientHandlerException");
		}

		return result;
	}

	/**
	 * GET请求的处理
	 * 
	 * @param server
	 *            Rest服务器地址
	 * @param restURI
	 *            RestAPI接口
	 * @param path
	 *            RestAPI接口地址
	 * @return 服务器返回内容
	 * @throws RESTFulException
	 *             截获此方法的所有异常，并统一throw MyException
	 */
	public static String get(String server, String restURI, String path) throws RESTFulException {
		String result = null;
		ClientResponse response = null;
		try {
			response = getWebResource(server, restURI).path(path).header("Content-Type", MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
			result = response.getEntity(String.class);

			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " get method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			t.printStackTrace();
			throw new RESTFulException(-1, "NetWorkError", "get method throw ClientHandlerException");
		}
		return result;
	}
	
	public static String getXml(String server, String restURI, String path) throws RESTFulException {
		String result = null;
		ClientResponse response = null;
		try {
			response = getWebResource(server, restURI).path(path).header("Accept", "text/html,application/xhtml+xml,application/xml;")
		    		.header("Accept-Language", "zh-cn")
		    		.header("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3")
		    		.header("Accept-Charset", "encoding")
		    		.header("Keep-Alive", "300")
		    		.header("Connection", "Keep-Alive")
		    		.header("Cache-Control", "no-cache").get(ClientResponse.class);
			result = response.getEntity(String.class);

			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " get method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			t.printStackTrace();
			throw new RESTFulException(-1, "NetWorkError", "get method throw ClientHandlerException");
		}
		return result;
	}

	/**
	 * GET请求的处理
	 * 
	 * @param server
	 *            Rest服务器地址
	 * @param restURI
	 *            RestAPI接口
	 * @param path
	 *            RestAPI接口地址
	 * @return 服务器返回内容
	 * @throws RESTFulException
	 *             截获此方法的所有异常，并统一throw MyException
	 */
	public static String get(String server, String restURI, String path, MultivaluedMap<String, String> params) throws RESTFulException {
		String result = null;
		ClientResponse response = null;
		try {
			response = getWebResource(server, restURI).path(path).queryParams(params).header("Content-Type", MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
			result = response.getEntity(String.class);

			int status = response.getStatus();
			if (status != Response.Status.OK.getStatusCode()) {
				throw new RESTFulException(-1, "response status!=200", " get method throw " + status + " Exception ");
			}
		} catch (RESTFulException e) {
			throw e;
		} catch (Throwable t) {
			t.printStackTrace();
			throw new RESTFulException(-1, "NetWorkError", "get method throw ClientHandlerException");
		}
		return result;
	}

	/**
	 * 将服务器返回内容转换成对象
	 * 
	 * @param str
	 * @param clazz
	 * @return
	 */
	public static <T> T jsonToBean(String str, Class<T> clazz) throws RESTFulException {
		ObjectMapper mapper = new ObjectMapper();
		T obj = null;
		try {
			obj = mapper.readValue(str.getBytes("utf-8"), clazz);
		} catch (Throwable e) {
			throw new RESTFulException(-1, "NetWorkError", "toBean method throw ConvertException,str=" + str + " , class=" + clazz + ",str=" + str);
		}
		return obj;
	}

	/**
	 * 将服务器返回内容转换成对象
	 * 
	 * @param str
	 * @param clazz
	 * @return
	 */
	public static <T> T xmlToBean(String str, Class<T> clazz) throws RESTFulException {
		T obj = null;
		try {
			obj = JaxbUtil.xmlStr2Obj(clazz, str);
		} catch (Throwable e) {
			throw new RESTFulException(-1, "NetWorkError", "toBean method throw ConvertException,str=" + str + " , class=" + clazz + ",str=" + str);
		}
		return obj;
	}
}